﻿using Beryl.OrderChanger;
using Beryl.OrderControllers.DBUpdate;
using Beryl.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Services.Description;
using System.Web.UI.WebControls;

namespace Beryl.OrderController
{
    //转生产订单
    public class orderController
    {
        private static orderController instance = null;
        private static readonly object uniqueLock = new object();

        public static orderController Instance
        {
            get
            {
                lock (uniqueLock)
                {
                    if (instance == null)
                    {
                        instance = new orderController();
                    }
                }
                return instance;
            }
        }
        public orderController() { }

        public List<string> getTableData(string para)
        {
            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
            List<string> list = new List<string>();
            string sql;
            string ret;
            try
            {
                string matType = "";
                string matYT = "";
                var k = jArray[0];
                string cProductDepNo = k["部门类型"].ToString();
                string type = k["订单状态"].ToString();
                string types = "";
                switch (cProductDepNo)
                {
                    case "Z21":
                        matType = "C02%"; //液态产品
                        matYT = "00B%";
                        break;
                    case "Z61":
                        matType = "C01%"; //固态产品
                        break;
                    case "Z01":
                        matType = "C%"; //所有产品
                        break;
                    default:
                        matType ="";
                        break;
                }

                switch(type)
                {
                    case "新订单":
                        types = "0000";
                        break;
                    case "已净需求":
                        types = "0010";
                        break;
                    case "已转生产订单":
                        types = "0020";
                        break;
                    case "已转生产批次":
                        types = "0050";
                        break;
                }

                sql = string.Format(@"SELECT a.AutoID,a.cParentSONo,a.cSONo,a.cMatNo,a.cCusNo,a.cCusName,a.dDate,a.dFinishDate,a.dQty,a.iSOsID," +
                    "case when (ISNULL(a.dQty,0) - ISNULL(d.dPlanQty1,0))>=0 then (ISNULL(a.dQty,0) - ISNULL(d.dPlanQty1,0)) else 0 end as dReQty," +
                    "ISNULL(d.dPlanQty1,0) as dAQty, CASE WHEN (e.dQty1 IS NULL AND e.cStatusNo < '0050')THEN (ISNULL(a.dQty,0) - ISNULL(d.dPlanQty1,0)) WHEN e.cStatusNo >= '0050' THEN 0 ELSE e.dQty1 END AS dQty1," +
                    "CASE WHEN (e.dNetQty IS NULL AND e.cStatusNo < '0050') THEN (ISNULL(a.dQty,0) - ISNULL(d.dPlanQty1,0)) WHEN e.cStatusNo >= '0050' THEN 0 ELSE e.dNetQty END AS dNetQty," +
                    "e.dNetQty2,e.dNetQty3,e.cReplyDeliveryDate,e.cStaUpdateTime,e.cStatusNo,ISNULL(e.cOFlag,'0') as cOFlag," +
                    " b.cMatName,b.cSpecifucation,LEFT(b.cSpecifucation,2) as cType,b.cCapacity,b.dVoltage,b.dDiameter,b.dheight,c.cStatusDesc,c.cNextStatusDesc FROM " +
                    "APS_ViewSOrder a LEFT JOIN APS_MatData_V b ON a.cMatNo = b.cMatNo " +
                    "LEFT JOIN (SELECT distinct cParentSONo,cMatNo,dQty1,dNetQty,dNetQty2,dNetQty3,cReplyDeliveryDate,iRowNo,cStatusNo,cStaUpdateTime,cOFlag,iSOsID FROM APS_SOrder) e " +
                    "ON a.cParentSONo = e.cParentSONo AND a.iRowNo = e.iRowNo AND a.iSOsID = e.iSOsID " +
                    "LEFT join APS_OrderStatus c ON e.cStatusNo = c.cStatusNo " +
                    "LEFT JOIN (SELECT cSourceNo,SUM(dPlanQty1) AS dPlanQty1 FROM APS_PlanOandSaleORelat group BY cSourceNo) d ON a.cSONo = d.cSourceNo " +
                    " WHERE (a.cMatNo LIKE '{0}' OR a.cMatNo LIKE '{1}') ", matType,matYT);

                if (k["销售订单号"].ToString() != "")
                {
                    sql += " and a.cParentSONo = '" + k["销售订单号"].ToString() + "'";
                }
                if(types.Equals("0000"))
                {
                    sql += string.Format(@"and(e.cStatusNo = '{0}' or e.cStatusNo is NULL)",types);
                }else
                {
                    sql += string.Format(@"and e.cStatusNo = '{0}' ", types);
                }
                sql += string.Format(@"and a.dDate >= '{0}' and a.dDate <= '{1}' AND(e.cReplyDeliveryDate >= '{2}' AND e.cReplyDeliveryDate <= '{3}'or e.cReplyDeliveryDate = '' or e.cReplyDeliveryDate is null)",
                    k["单据日期开始"].ToString(), k["单据日期结束"].ToString(), k["答复日期开始"].ToString(), k["答复日期结束"].ToString());

                sql += string.Format(@"ORDER BY a.dDate DESC,a.cParentSONo,cast(a.iRowNo as int);");

                //DataTable dt = new DataTable();
                //int index = int.Parse(k["index"].ToString());
                //int pageSize = int.Parse(k["page"].ToString());
                //dt = CheckData.Instance.GetData(index,pageSize, sql, out total);
                ret = JsonConvert.SerializeObject(CommonMethod.Instance.selectDatabase(sql));//转为json
                list.Add(ret);
                //list.Add(total.ToString());

            }
            catch(Exception e)
            {
                list.Add(e.Message);
            }
            return list;
        }

        //销售订单增加
        public List<string> SaleOrderAdd(string para)
        {
            List<string> list = new List<string>();
            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
            try
            {
                var k = jArray[0];
                var cParentSONo = k["cParentSONo"].ToString();
                var cSONo = k["cSONo"].ToString();
                var cMatNo = k["cMatNo"].ToString();
                var dQty = k["dQty"].ToString();

                //   var cOFlag = Textbox5.Text;
                var cCusNo = k["cCusNo"].ToString();
                var cCusName = k["cCusName"].ToString();
                var dDate = k["dDate"].ToString();
                var dFinishDate = k["dFinishDate"].ToString();

                var sqlString = string.Format(@"INSERT INTO APS_SOrder(cParentSONo, cSONo, cMatNo, dQty, cStatusNo,cCusNo, cCusName, dDate, dFinishDate) " +
                    "VALUES('{0}', '{1}', '{2}',{3},'0000','{4}','{5}','{6}','{7}');", cParentSONo, cSONo, cMatNo, dQty, cCusNo, cCusName, dDate, dFinishDate);
                List<string> strings = new List<string>
                {
                    sqlString
                };
                bool ok = CommonMethod.Instance.insertSqlList(strings);
                if (!ok)
                {
                    throw new Exception("增加销售订单失败");
                }
                list.Add("success");
            }
            catch(Exception e)
            {
                list.Add(e.Message);
            }
            return list;
        }

        //更新销售订单
        public List<string> SaleOrderUpdate(string para)
        {
            List<string> list = new List<string>();
            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
            try
            {
                string sql1 = "";
                for(int i = 0; i < jArray.Count; i++) //jArray.Count = 1 
                {
                    string cStatusNo = jArray[i]["cStatusNo"].ToString();
                    string cSONo = jArray[i]["cSONo"].ToString();
                    string dQty1 = jArray[i]["dQty1"].ToString();
                    string dNetQty = jArray[i]["dNetQty"].ToString();
                    string dFinishDate = jArray[i]["dFinishDate"].ToString();
                    if(cStatusNo.Equals("0020"))
                    {
                         sql1 = string.Format(@"UPDATE APS_SOrder SET dFinishDate = '{0}', dNetQty = '{1}',
                        dQty1 = '{2}'
                        WHERE 
                            cSONo ='{3}'; 
                        UPDATE APS_PlanOrder 
                        SET 
                            dDeliveryDate = '{4}' ,
                            dPlanQty = '{5}'
                            dPlanQty1 = '{6}'
                        WHERE 
                            cPOrderNo = (SELECT cPOrderNo FROM APS_PlanOandSaleORelat WHERE cSourceNo = '{7}');",dFinishDate, dNetQty, dQty1, cSONo, dFinishDate, dNetQty, dQty1, cSONo);
                    }

                    if(cStatusNo.Equals("0000") || cStatusNo.Equals("0010") || cStatusNo.Equals("0050"))
                    {
                        sql1 = string.Format(@"UPDATE APS_SOrder SET dFinishDate = '{0}', 
                            dNetQty = {1},
                            dQty1 = {2}
                        WHERE 
                            cSONo ='{3}';", dFinishDate, dNetQty, dQty1, cSONo); 
                    }
                }
                List<string> strings = new List<string>
                {
                    sql1
                };
                bool ok = CommonMethod.Instance.insertSqlList(strings);
                if (!ok)
                {
                    throw new Exception("更新销售订单失败");
                }
                list.Add("success");
            }
            catch(Exception e)
            {
                list.Add(e.Message);
            }
            return list;
        }

        //转生产订单处理
        public List<string> changeOrderDeal(string para)
        {
            List<string> retList = new List<string>();
            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(para);
            int SorderDay = 0;
            string SorderDayLimit;
            float SorderNum = 0;
            string SorderNumLimit = "";
            float MAXOrderNum = 0;
            string MAXOrderNumLimit = "";
            int AutoID = 0;
            Dictionary<string, DataRow> SerialNoObj = new Dictionary<string, DataRow>();
            Dictionary<string, Dictionary<string,float>> PlanOandSaleObj = new Dictionary<string, Dictionary<string, float>>();
            Dictionary<string, Dictionary<string, string>> BomObj = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, List<DataRow>> OrderCoeffObj = new Dictionary<string, List<DataRow>>();
            string str = "";
            try
            {
                var jArrayT = jArray[0];//第一条json
                var JArrayT1 = jArray[1];//第二条json
                string cSorderNo = jArrayT["cSOrderID"].ToString();
                Newtonsoft.Json.Linq.JArray cSorderNoArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(cSorderNo);
                string cProductDepNo = JArrayT1["cProductDepNo"].ToString();

                // 1.合并销售订单时间间隔
                string TSC_InvalidDateNum = string.Format(@"SELECT * FROM APS_PlanConfig " +
                    "WHERE cRuleName = 'InvalidDateNumLimit' AND cProductDepNo = '{0}';", cProductDepNo);
                //var InvalidDateNum = CommonMethod.Instance.selectDatabase(TSC_InvalidDateNum);
                //var InvalidDateNumRow = InvalidDateNum.Select($"cProductDepNo = '{JArrayT1["cProductDepNo"].ToString()}'"); 
                var InvalidDateNumRow = CommonMethod.Instance.retData(TSC_InvalidDateNum, "cProductDepNo", cProductDepNo);
                if (InvalidDateNumRow.Length > 0)
                {
                    if(InvalidDateNumRow[0]["cRuleValue"].ToString() != "")
                    {
                        SorderDay = int.Parse(InvalidDateNumRow[0]["cRuleValue"].ToString());
                    }
                     SorderDayLimit = InvalidDateNumRow[0]["cIsActive"].ToString();
                }

                // 2.合并销售订单数量
                string TSC_SaleOrderNum = string.Format("SELECT * FROM APS_PlanConfig WHERE cRuleName = 'SaleOrderNumLimit' AND cProductDepNo = '{0}';", JArrayT1["cProductDepNo"].ToString());
                //var SaleOrderNum = CommonMethod.Instance.selectDatabase(TSC_SaleOrderNum);
                //var SaleOrderNumRow = SaleOrderNum.Select($"cProductDepNo = '{JArrayT1["cProductDepNo"].ToString()}'");
                var SaleOrderNumRow = CommonMethod.Instance.retData(TSC_SaleOrderNum, "cProductDepNo", cProductDepNo);
                if (SaleOrderNumRow.Length > 0)
                {
                    if(SaleOrderNumRow[0]["cRuleValue"].ToString() != "")
                    {
                        SorderNum = float.Parse(SaleOrderNumRow[0]["cRuleValue"].ToString());
                    }
                     
                     SorderNumLimit = SaleOrderNumRow[0]["cIsActive"].ToString();
                }

                // 3.计划订单产品上限数
                string TSC_PlanOrderProductNum = string.Format(@"SELECT * FROM APS_PlanConfig WHERE cRuleName = 'PlanOrderProductNumLimit' AND cProductDepNo = '{0}';", JArrayT1["cProductDepNo"].ToString());
                //var PlanOrderProductNum = CommonMethod.Instance.selectDatabase(TSC_SaleOrderNum);
                //var PlanOrderProductNumRow = PlanOrderProductNum.Select($"cProductDepNo = '{JArrayT1["cProductDepNo"].ToString()}'");
                var PlanOrderProductNumRow = CommonMethod.Instance.retData(TSC_PlanOrderProductNum, "cProductDepNo", cProductDepNo);
                if (PlanOrderProductNumRow.Length > 0)
                {
                    if(PlanOrderProductNumRow[0]["cRuleValue"].ToString() != "")
                    {
                        MAXOrderNum = float.Parse(PlanOrderProductNumRow[0]["cRuleValue"].ToString());
                    }
                    MAXOrderNumLimit = PlanOrderProductNumRow[0]["cIsActive"].ToString();
                }

                string MotypeCode = cProductDepNo == "Z61" ? "GA" : "YA";
                string Description = cProductDepNo == "Z61" ? "正常生产（固态）" : "正常生产";
                string flag = cProductDepNo == "Z61" ? "PG" : "P";
                if (cSorderNoArr.Count == 0)
                {
                    throw new Exception("cSorderNoArr 为 null");
                }
                else
                {
                    string APS_PlanOrder = string.Format(@"SELECT max(AutoID) as MaxID FROM APS_PlanOrder");
                    //var PlanOrder = CommonMethod.Instance.selectDatabase(APS_PlanOrder);
                    //var PlanOrderRow = PlanOrder.Select("1=1");
                    var PlanOrderRow = CommonMethod.Instance.retData(APS_PlanOrder, "", "");
                    if (PlanOrderRow.Length > 0)
                    {
                        // 生产订单的ID
                        AutoID = int.Parse(PlanOrderRow[0]["MaxID"].ToString());
                        string retID = "";
                        for(int i = 0; i < cSorderNoArr.Count; i++)
                        {
                            if(i != cSorderNoArr.Count - 1)
                            {
                                retID += cSorderNoArr[i] + ",";
                            }else
                            {
                                retID += cSorderNoArr[i];
                            }
                            
                        }
                        // 销售订单
                        string APS_SOrder = string.Format(@"SELECT a.AutoID,a.cParentSONo,a.iRowNo,a.iSOsID,a.cSONo,a.cMatNo,a.dQty," +
                        "CASE WHEN f.cCusDefine10 IS NOT NULL THEN f.cCusDefine10 ELSE a.cCusName END AS cCusName,CASE WHEN (a.cSONo LIKE 'SSS%' ) THEN '5A' ELSE c.iPriority END AS iPriority," +
                        "e.cStatusNo,e.dQty1,e.dNetQty,e.dNetQty2,e.dNetQty3,e.cReplyDeliveryDate,e.dFinishDate,c.cCusNo,m.cProductDepNo,m.cProductDepName,m.dProBatch,m.dDiameter,m.cPeriod " +
                        "FROM APS_ViewSOrder a LEFT JOIN APS_CusPriority_V c ON a.cCusNo = c.cCusNo " +
                        "LEFT JOIN (SELECT cParentSONo,cMatNo,dQty1,dNetQty,dNetQty2,dNetQty3,cReplyDeliveryDate,iRowNo,cStatusNo,cStaUpdateTime,cOFlag ,dFinishDate FROM APS_SOrder) e " +
                        "ON a.cParentSONo = e.cParentSONo AND a.iRowNo = e.iRowNo " +
                        "LEFT JOIN APS_MatData_V m ON a.cMatNo = m.cMatNo " +
                        "LEFT JOIN APS_CusPriority_V f ON a.cCusNo = f.cCusNO " +
                        "WHERE a.AutoID in ({0});", retID);
                        //var SOrder = CommonMethod.Instance.selectDatabase(APS_SOrder);
                        //var SOrderRow = SOrder.Select("1 = 1");
                        var SOrderRow = CommonMethod.Instance.retData(APS_SOrder, "", "");

                        string OrderCoefficient = string.Format(@"SELECT Id,Diameter,UpperNum,LowerNum,Coefficient,Ptype FROM OrderCoefficient");
                        //var Coefficient = CommonMethod.Instance.selectDatabase(OrderCoefficient);
                        //var CoefficientRow = Coefficient.Select("1 = 1");
                        var CoefficientRow = CommonMethod.Instance.retData(OrderCoefficient, "", "");

                        //当前流水码
                        string SerialNo = string.Format(@"SELECT cType,iSerialNo,cDate FROM APS_SerialNo WHERE cType in ('P','PG','PR')");
                        //var Serial = CommonMethod.Instance.selectDatabase(SerialNo);
                        //var SerialRow = Serial.Select("1 = 1");
                        var SerialRow = CommonMethod.Instance.retData(SerialNo, "", "");

                        //生产订单与销售订单关系
                        string PlanOandSale = string.Format(@"SELECT p.cSourceNo,p.dPlanQty1,s.AutoID " +
                        "FROM APS_PlanOandSaleORelat p LEFT JOIN APS_ViewSOrder s ON p.cSourceNo = s.cSONo" +
                        " WHERE s.AutoID in ({0})", retID);
                        //var OandSale = CommonMethod.Instance.selectDatabase(PlanOandSale);
                        //var OandSaleRow = OandSale.Select("1 = 1");
                        var OandSaleRow = CommonMethod.Instance.retData(PlanOandSale, "", "");

                        string CManuBOM = string.Format(@"SELECT cMatNo,RelsUser FROM APS_CmatManuBOM_V WHERE 1 = 1");
                        //var CManu = CommonMethod.Instance.selectDatabase(CManuBOM);
                        //var CManuRow = CManu.Select("1 = 1");
                        var CManuRow = CommonMethod.Instance.retData(CManuBOM, "", "");

                        //销售订单时间限制
                        string SorderLimit = string.Format(@"SELECT cIsActive,cRuleValue FROM APS_PlanConfig WHERE cRuleName='InvalidDateNumLimit' AND cProductDepNo = '{0}';", cProductDepNo);
                        //var SorderLimitSelect = CommonMethod.Instance.selectDatabase(SorderLimit);
                        //var SorderLimitRow = SorderLimitSelect.Select("1 = 1");
                        var SorderLimitRow = CommonMethod.Instance.retData(SorderLimit, "", "");

                        SorderDayLimit = SorderLimitRow[0]["cIsActive"].ToString();
                        for (int i = 0; i < SerialRow.Length; i++)
                        {
                            string cType = SerialRow[i]["cType"].ToString();
                            if (!SerialNoObj.ContainsKey(cType))//不存在key值
                            {
                                SerialNoObj.Add(cType, null);
                            }
                            SerialNoObj[cType] = SerialRow[i];
                        }

                        Dictionary<string, float> dicOandSale = new Dictionary<string, float>();
                        //生产订单与销售订单关系 
                        for (int i = 0; i < OandSaleRow.Length; i++)
                        {
                            string cSourceNo = OandSaleRow[i]["cSourceNo"].ToString();
                            if (!PlanOandSaleObj.ContainsKey(cSourceNo))
                            {
                                dicOandSale.Clear();
                                dicOandSale.Add("dPlanQty1", float.Parse(OandSaleRow[i]["dPlanQty1"].ToString()));
                                PlanOandSaleObj.Add(cSourceNo, dicOandSale);
                            }
                            else
                            {
                                dicOandSale.TryGetValue("dPlanQty1", out float outValue);
                                float newValue = float.Parse(OandSaleRow[i]["dPlanQty1"].ToString()) + outValue;
                                dicOandSale["dPlanQty1"] = newValue;
                                PlanOandSaleObj[cSourceNo] = dicOandSale;
                            }
                        }

                        Dictionary<string, string> dicBom = new Dictionary<string, string>();
                        //BomObj
                        for (int i = 0; i < CManuRow.Length; i++)
                        {
                            string cMatNo = CManuRow[i]["cMatNo"].ToString();
                            if (!BomObj.ContainsKey(cMatNo))
                            {
                                BomObj.Add(cMatNo, dicBom);
                            }
                        }

                        // 损耗系数
                        List<DataRow> dataRows = new List<DataRow>();
                        for (int i = 0; i < CoefficientRow.Length; i++)
                        {
                            string Diameter = CoefficientRow[i]["Diameter"].ToString();
                            if (!OrderCoeffObj.ContainsKey(Diameter))
                            {
                                dataRows = new List<DataRow>();
                                OrderCoeffObj.Add(Diameter, null);
                            }
                            dataRows.Add(CoefficientRow[i]);
                            OrderCoeffObj[Diameter] = dataRows;
                        }

                        // 更新销售订单的净需求
                        Dictionary<string, Dictionary<string, string>> cSONos = new Dictionary<string, Dictionary<string, string>>();
                        Dictionary<string, List<string>> cSouArr = new Dictionary<string, List<string>>();
                        // 销售订单已转生产的毛需求数
                        float ddPlanQty1 = 0;
                        // 选中的销售订单不同客户数
                        int length = 0;
                        // 生产订单号
                        string planOrderNo = "";
                        string Today = CommonMethod.Instance.getTimes().Split(' ')[0];
                        int serialNum = 0;
                        string serialStr = "";

                        if (cProductDepNo == "Z21")
                        {
                            SerialNoObj.TryGetValue("P", out DataRow row);
                            string cDate = row["cDate"].ToString();
                            if (cDate.Equals(Today))
                            {
                                serialNum = int.Parse(row["iSerialNo"].ToString());  // 流水号
                                if (serialNum == 500)
                                {
                                    //return { resCode: "failed",resMsg:` 转生产订单失败：超出一天最大转单数`,data: { } };
                                    throw new Exception("转生产订单失败：超出一天最大转单数");
                                }
                            }
                        }

                        if (cProductDepNo == "Z61")
                        {
                            SerialNoObj.TryGetValue("PG", out DataRow row);
                            string cDate = row["cDate"].ToString();
                            if (cDate.Equals(Today))
                            {
                                serialNum = int.Parse(row["iSerialNo"].ToString());  // 流水号
                                if (serialNum == 800)
                                {
                                    throw new Exception("转生产订单失败：超出一天最大转单数");
                                }
                            }
                            else
                            {
                                serialNum = 501;
                            }
                        }

                        List<string> list = new List<string>();
                        Dictionary<string, string> dic1 = new Dictionary<string, string>();
                        Dictionary<string, Dictionary<string, Dictionary<string, string>>> planOrder = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
                        Dictionary<string, Dictionary<string, string>> planOrder1 = new Dictionary<string, Dictionary<string, string>>();
                        Dictionary<string, string> planOrder2 = new Dictionary<string, string>();

                        // 遍历销售订单
                        for (int i = 0; i < SOrderRow.Length; i++)
                        {
                            // 母单号
                            string cParentSONo = SOrderRow[i]["cParentSONo"].ToString();
                            // 行号
                            string iRowNo = SOrderRow[i]["iRowNo"].ToString();
                            string iSOsID = SOrderRow[i]["iSOsID"].ToString();
                            string dDiameter = SOrderRow[i]["dDiameter"].ToString();
                            string cPeriod = SOrderRow[i]["cPeriod"].ToString();
                            string putProQty;
                            int Coefficient1 = 1;

                            // 销售订单ID
                            string sAutoID = SOrderRow[i]["AutoID"].ToString();

                            if (!cSONos.ContainsKey(sAutoID))
                            {
                                dic1 = new Dictionary<string, string>();
                                cSONos.Add(sAutoID, null);
                            }

                            // 子销售订单号
                            string cSONo = SOrderRow[i]["cSONo"].ToString();
                            if (PlanOandSaleObj.ContainsKey(cSONo))
                            {
                                PlanOandSaleObj.TryGetValue(cSONo, out Dictionary<string, float> newDic);
                                ddPlanQty1 = newDic["dPlanQty1"];
                            }

                            // 物料编号
                            string cMatNo = SOrderRow[i]["cMatNo"].ToString();
                            if (!BomObj.ContainsKey(cMatNo))
                            {
                                //return {resCode:"failed",resMsg:` 转生产订单失败：${cMatNo}未审核,${cSONo}订单暂时不能转单,请取消勾选 `,data:{}};
                                throw new Exception("failed(转生产订单失败:" + cMatNo + "未审核," + cSONo + "订单暂时不能转单,请取消勾选)");
                            }

                            // 客户编号
                            string cCusNo = SOrderRow[i]["cCusNo"].ToString();
                            string cCusName = SOrderRow[i]["cCusName"].ToString();
                            string cReworkFlag = "0";
                            string dProBatch = SOrderRow[i]["dProBatch"].ToString();
                            string dPlanQty1 = SOrderRow[i]["dQty1"].ToString(); //加工需求

                            // 净需求
                            string dTotalQty3 = SOrderRow[i]["dNetQty3"].ToString();// FIXME 净需求字段 dNetQty3
                            string dTotalQty2 = SOrderRow[i]["dNetQty2"].ToString();// FIXME 净需求字段 dNetQty2
                            string dTotalQty1 = SOrderRow[i]["dNetQty"].ToString();// FIXME 净需求字段 dNetQty1

                            // 中间量
                            float dTotalQty0;

                            // 如果修改料加工需求
                            if (dPlanQty1 != "")
                            {
                                dTotalQty0 = float.Parse(dPlanQty1);
                            }
                            else
                            {
                                dPlanQty1 = SOrderRow[i]["dQty"].ToString();
                                dTotalQty0 = float.Parse(SOrderRow[i]["dQty"].ToString());
                            }

                            // 如果销售订单所有毛需求都转生产订单
                            if ((float.Parse(dPlanQty1) + ddPlanQty1) >= float.Parse(SOrderRow[i]["dQty"].ToString()))
                            {
                                if (!cSouArr.ContainsKey(cParentSONo))
                                {
                                    list = new List<string>();
                                    cSouArr.Add(cParentSONo, null);
                                }
                                list.Add(iRowNo);
                                cSouArr[cParentSONo] = list;
                            }

                            // 如果修改了钉卷需求
                            if (dTotalQty1 != "")
                            {
                                dic1.Add("dNetQty", dTotalQty1);
                                cSONos[sAutoID] = dic1;
                            }
                            else
                            {
                                dTotalQty1 = dTotalQty0.ToString();
                                dic1.Add("dNetQty", dTotalQty1);
                                cSONos[sAutoID] = dic1;
                            }

                            float dTotalQty = 0;
                            string cProductDepNoD = SOrderRow[i]["cProductDepNo"].ToString();
                            string cProductDepName = SOrderRow[i]["cProductDepName"].ToString();
                            // 答复交货期
                            string dDeliveryDate = SOrderRow[i]["dFinishDate"].ToString();

                            if(dTotalQty3 == "")
                            {
                                dTotalQty3 = "-0.1";
                            }
                            if(dTotalQty2 == "")
                            {
                                dTotalQty2 = "-0.1";
                            }
                            if(dTotalQty1 == "")
                            {
                                dTotalQty1 = "-0.1";
                            }

                            //若销售订单净需求都<=0，则 continue   
                            if (float.Parse(dTotalQty3) <= 0)
                            {
                                if (float.Parse(dTotalQty2) <= 0)
                                {
                                    if (float.Parse(dTotalQty1) <= 0)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        dTotalQty = float.Parse(dTotalQty1);
                                    }
                                }
                                else
                                {
                                    dTotalQty = float.Parse(dTotalQty2);
                                }
                            }
                            else
                            {
                                dTotalQty = float.Parse(dTotalQty3);
                                dPlanQty1 = dTotalQty3;
                                dic1["dNetQty"] = "0";
                                cSONos[sAutoID] = dic1;
                                cReworkFlag = "1";
                            }
                            // 初始化生成计划订单（没有相同客户）
                            bool tmp_flag = false;
                            if (!planOrder.ContainsKey(cCusNo))
                            {
                                planOrder1 = new Dictionary<string, Dictionary<string, string>>();
                                planOrder2 = new Dictionary<string, string>();
                                ++length;
                                serialStr = CommonMethod.Instance.GenerateID(++serialNum, "000");
                                planOrderNo = str + CommonMethod.Instance.getTimes2() + serialStr;
                                //planOrderNo = `${new Date().Format("yyMMdd")}${serialNum}`;
                                AutoID++;
                                planOrder.Add(cCusNo, null);
                                planOrder1.Add(planOrderNo, null);
                                Dictionary<string, string> jsonDic = new Dictionary<string, string>
                                {
                                    { "cSONo", cSONo },
                                    { "dTotalQty", dTotalQty.ToString() },
                                    { "dPlanQty1", dPlanQty1 }
                                };

                                string json = JsonConvert.SerializeObject(jsonDic);
                                planOrder2.Add("json", json);
                                planOrder2.Add("Num", dTotalQty.ToString());
                                planOrder2.Add("Coefficient", Coefficient1.ToString());
                                planOrder2.Add("putProQty", dPlanQty1);
                                planOrder2.Add("dPlanQty1", dPlanQty1);
                                planOrder2.Add("DepNo", cProductDepNo);
                                planOrder2.Add("DepName", cProductDepName);
                                planOrder2.Add("DeliveryDate", dDeliveryDate);
                                planOrder2.Add("MatNo", cMatNo);
                                planOrder2.Add("cReworkFlag", cReworkFlag);
                                planOrder2.Add("AutoID", AutoID.ToString());
                                planOrder2.Add("cCusName", cCusName);
                                planOrder2.Add("MotypeCode", MotypeCode);
                                planOrder2.Add("Description", Description);
                                planOrder2.Add("dProBatch", dProBatch);
                                planOrder2.Add("cMakeTime", Today);
                                planOrder2.Add("cParentSONo", cParentSONo);
                                planOrder2.Add("iRowNo", iRowNo);
                                planOrder2.Add("iSOsID", iSOsID);

                                jsonDic = new Dictionary<string, string>
                                {
                                    { "cosNum", cSONo }
                                };
                                string json1 = JsonConvert.SerializeObject(jsonDic);
                                planOrder2.Add("json1", json1);
                                planOrder1[planOrderNo] = planOrder2;
                                planOrder[cCusNo] = planOrder1;
                                tmp_flag = true;
                            }
                            else // 同一客户的不同订单
                            {
                                foreach (var planOrderNo_tmp in planOrder[cCusNo].Keys)
                                {
                                    planOrder[cCusNo][planOrderNo_tmp].TryGetValue("MatNo", out string newMatNo);
                                    if (newMatNo.Equals(cMatNo))
                                    {
                                        planOrder[cCusNo][planOrderNo_tmp].TryGetValue("json1", out string newJson1);
                                        Dictionary<string, string> dict = new Dictionary<string, string>();
                                        dict.Add("cosNum", cSONo);
                                        string json1 = JsonConvert.SerializeObject(dict);
                                        string retJson1 = CommonMethod.Instance.JsonAddItem(newJson1, json1);
                                        planOrder[cCusNo][planOrderNo_tmp]["json1"] = retJson1;
                                        if (SorderDayLimit == "1")
                                        {
                                            planOrder[cCusNo][planOrderNo_tmp].TryGetValue("DeliveryDate", out string startTime);
                                            string endTime = dDeliveryDate;
                                            int timeOut = CommonMethod.Instance.diffDate(endTime, startTime);
                                            if (timeOut <= SorderDay)
                                            {
                                                Dictionary<string, string> jsonDic = new Dictionary<string, string>
                                                    {
                                                        { "cSONo", cSONo },
                                                        { "dTotalQty", dTotalQty.ToString() },
                                                        { "dPlanQty1", dPlanQty1 }
                                                    };
                                                string json = JsonConvert.SerializeObject(jsonDic);
                                                planOrder[cCusNo][planOrderNo_tmp].TryGetValue("json", out string newJson);
                                                string retJson = CommonMethod.Instance.JsonAddItem(newJson, json);
                                                planOrder[cCusNo][planOrderNo_tmp]["json"] = retJson;
                                                planOrder[cCusNo][planOrderNo_tmp].TryGetValue("Num", out string NewNum);
                                                float newNumText = float.Parse(NewNum) + dTotalQty;
                                                planOrder[cCusNo][planOrderNo_tmp]["Num"] = newNumText.ToString();

                                                planOrder[cCusNo][planOrderNo_tmp].TryGetValue("dPlanQty1", out string NewdPlanQty1);
                                                float NewdPlanQty1Text = float.Parse(NewdPlanQty1) + float.Parse(dPlanQty1);
                                                planOrder[cCusNo][planOrderNo_tmp]["dPlanQty1"] = NewdPlanQty1Text.ToString();
                                                planOrder[cCusNo][planOrderNo_tmp]["DeliveryDate"] = dDeliveryDate;
                                                tmp_flag = true;
                                                break;
                                            }
                                            else
                                            {
                                                //logger.info(`该订单因合并订单时间间隔限制无法合批（单独成批）：${cSONo}-${dDeliveryDate}-${cMatNo}-${dTotalQty}`);
                                            }
                                        }

                                        if (SorderNumLimit == "1")
                                        {
                                            planOrder[cCusNo][planOrderNo_tmp].TryGetValue("json1", out string NewJson1);
                                            Newtonsoft.Json.Linq.JArray JsonArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(NewJson1);
                                            if (JsonArray.Count <= SorderNum)
                                            {
                                                Dictionary<string, string> jsonDic = new Dictionary<string, string>
                                                    {
                                                        { "cSONo", cSONo },
                                                        { "dTotalQty", dTotalQty.ToString() },
                                                        { "dPlanQty1", dPlanQty1 }
                                                    };
                                                string json = JsonConvert.SerializeObject(jsonDic);
                                                planOrder1[planOrderNo_tmp].TryGetValue("json", out string newJson);
                                                string retJson = CommonMethod.Instance.JsonAddItem(newJson, json);
                                                planOrder[cCusNo][planOrderNo_tmp]["json"] = retJson;

                                                planOrder[cCusNo][planOrderNo_tmp].TryGetValue("Num", out string NewNum);
                                                float newNumText = float.Parse(NewNum) + dTotalQty;
                                                planOrder[cCusNo][planOrderNo_tmp]["Num"] = newNumText.ToString();

                                                planOrder[cCusNo][planOrderNo_tmp].TryGetValue("dPlanQty1", out string NewdPlanQty1);
                                                float NewdPlanQty1Text = float.Parse(NewdPlanQty1) + float.Parse(dPlanQty1);
                                                planOrder[cCusNo][planOrderNo_tmp]["dPlanQty1"] = NewdPlanQty1Text.ToString();
                                                planOrder[cCusNo][planOrderNo_tmp]["DeliveryDate"] = dDeliveryDate;
                                                tmp_flag = true;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            //logger.info(`该订单因合并订单数量限制无法合批（单独成批）：${cSONo}-${dDeliveryDate}-${cMatNo}-${dTotalQty}`);
                                        }

                                        // 生产订单产品数量约束
                                        if (MAXOrderNumLimit == "1")
                                        {
                                            planOrder[cCusNo][planOrderNo_tmp].TryGetValue("Num", out string NewNum);
                                            float NewNumDt = float.Parse(NewNum) + dTotalQty;
                                            if (NewNumDt <= MAXOrderNum)
                                            {
                                                Dictionary<string, string> jsonDic = new Dictionary<string, string>
                                                    {
                                                        { "cSONo", cSONo },
                                                        { "dTotalQty", dTotalQty.ToString() },
                                                        { "dPlanQty1", dPlanQty1 }
                                                    };
                                                string json = JsonConvert.SerializeObject(jsonDic);
                                                planOrder1[planOrderNo_tmp].TryGetValue("json", out string newJson);
                                                string retJson = CommonMethod.Instance.JsonAddItem(newJson, json);
                                                planOrder[cCusNo][planOrderNo_tmp]["json"] = retJson;
                                                planOrder[cCusNo][planOrderNo_tmp]["Num"] = NewNumDt.ToString();
                                                planOrder[cCusNo][planOrderNo_tmp]["dPlanQty1"] = dTotalQty.ToString();
                                                planOrder[cCusNo][planOrderNo_tmp]["DeliveryDate"] = dDeliveryDate;
                                                tmp_flag = true;
                                                break;
                                            }
                                            else
                                            {
                                                //logger.info(`该订单因生产订单产品数量限制无法合批（单独成批）：${cSONo}-${dDeliveryDate}-${cMatNo}-${dTotalQty}`);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //logger.info(`该订单因物料不同限制无法合批（单独成批）：${cSONo}-${dDeliveryDate}-${cMatNo}-${dTotalQty}`);
                                    }
                                }
                            }
                            // 该订单仍未合批，单独成批
                            if (!tmp_flag)
                            {
                                planOrder1 = new Dictionary<string, Dictionary<string, string>>();
                                planOrder2 = new Dictionary<string, string>();
                                serialStr = CommonMethod.Instance.GenerateID(++serialNum, "000");
                                planOrderNo = str + CommonMethod.Instance.getTimes2() + serialStr;
                                AutoID++;
                                planOrder1.Add(planOrderNo, null);
                                Dictionary<string, string> jsonDic = new Dictionary<string, string>
                                     {
                                        { "cSONo", cSONo },
                                        { "dTotalQty", dTotalQty.ToString() },
                                        { "dPlanQty1", dPlanQty1 }
                                      };
                                string json = JsonConvert.SerializeObject(jsonDic);
                                planOrder2.Add("json", json);
                                planOrder2.Add("Num", dTotalQty.ToString());
                                planOrder2.Add("Coefficient", Coefficient1.ToString());
                                planOrder2.Add("putProQty", dPlanQty1);
                                planOrder2.Add("dPlanQty1", dPlanQty1);
                                jsonDic = new Dictionary<string, string>
                                {
                                    { "cosNum", cSONo }
                                };
                                string json1 = JsonConvert.SerializeObject(jsonDic);
                                planOrder2.Add("json1", json1);
                                planOrder2.Add("DepNo", cProductDepNo);
                                planOrder2.Add("DepName", cProductDepName);
                                planOrder2.Add("DeliveryDate", dDeliveryDate);
                                planOrder2.Add("MatNo", cMatNo);
                                planOrder2.Add("cReworkFlag", cReworkFlag);
                                planOrder2.Add("AutoID", AutoID.ToString());
                                planOrder2.Add("cCusName", cCusName);
                                planOrder2.Add("MotypeCode", MotypeCode);
                                planOrder2.Add("Description", Description);
                                planOrder2.Add("dProBatch", dProBatch);
                                planOrder2.Add("cMakeTime", Today);
                                planOrder2.Add("cParentSONo", cParentSONo);
                                planOrder2.Add("iRowNo", iRowNo);
                                planOrder2.Add("iSOsID", iSOsID);
                                planOrder[cCusNo][planOrderNo] = planOrder2;
                            }
                        }
                        //数据库插入
                        if(!OrderUpdate.Instance.updatePlanOrder(planOrder, cSouArr))
                        {
                            throw new Exception("updatePlanOrder:插入失败");
                        }

                        if(!OrderUpdate.Instance.updateSerialNo(Today, serialStr, cProductDepNo))
                        {
                            throw new Exception("updateSerialNo:插入失败");
                        }

                        if (cSONos.Keys.Count > 0)
                        {
                            if(!OrderUpdate.Instance.updateSONoNetQty(cSONos))
                            {
                                throw new Exception("updateSONoNetQty:插入失败");
                            }
                        }
                        retList.Add("[0]");
                    }
                }
            }
            catch (Exception e)
            {
                retList.Add(e.Message);
            }
            return retList;
        }

    }
}